﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace DataTypes
{
    /// <summary>
    /// This class describes all the tweakable options used to control
    /// the appearance of a particle system
    /// </summary>
    public class ParticleSettings
    {
        // The name of the texture used by this particle system
        public string TextureName = null;

        // Maximum number of particles to be displayed at any one time
        public int MaxParticles = 100;

        // How long these particles will last
        public TimeSpan Duration = TimeSpan.FromSeconds(1);

        // If this value is greater than zero, then some particles will last longer than other
        public float DurationRandomness = 0;

        // Control how much particles are influenced by the velocity of the object that creates them
        // Set this value very low so they are less affected by the velocity of the object
        public float EmitterVelocitySensitivity = 1;

        // Range of values controlling how much X and Z axis velocity to give each particle.
        // Values for individual particles are randomly chosen from somewhere between these values
        public float MinHorizontalVelocity = 0;
        public float MaxHorizontalVelocity = 0;

        // Same thing, this time for the Y axis
        public float MinVerticalVelocity = 0;
        public float MaxVerticalVelocity = 0;

        // The direction and strength of the gravity effect. 
        // This can point in any direction
        public Vector3 Gravity = Vector3.Zero;

        // Controls how a particle velocity will change over the particles lifetime
        // If set to 1 the particles will keep going the same speed they were originally created
        // If set to 0 the particles will come to a complete stop right before they die
        // Values over 1 will increase the speed of the particle
        public float EndVelocity = 1;

        // Range of values that control the particles colour and alpha value
        // The value for these individual particles can be randomly chosen between these values
        public Color MinColor = Color.White;
        public Color MaxColor = Color.White;

        // Range of values that control how fast the particles will rotate
        // Values again are randomly chosen between these two values
        // If both are set to 0, the particle system will switch to a different shader setting
        // that doesnt support rotation, to reduce the GPU load. Therefore if we dont need rotation
        // dont use it, as the performance boost may be worthwhile especially on the 360
        public float MinRotateSpeed = 0;
        public float MaxRotateSpeed = 0;

        // These values control how big the particles are when they are first created
        // Again these values will be randomly decided per particle
        // between the two given values
        public float MinStartSize = 100;
        public float MaxStartSize = 100;

        // Range of values controlling how big particles will be, at the end of their life cycle
        public float MinEndSize = 100;
        public float MaxEndSize = 100;

        // Alpha Blending Settings
        // Ignore this from the XML file
        [ContentSerializerIgnore]
        public BlendState BlendState = BlendState.NonPremultiplied;

        // Allow a blendstate for the particle to be chosen
        // More blendstates can be added if needed, however
        // the ones in this are the most common for particles
        [ContentSerializer(ElementName = "BlendState")]
        private string BlendStateSerializationHelper
        {
            get { return BlendState.Name.Replace("BlendState.", string.Empty); }

            set
            {
                switch (value)
                {
                    case "AlphaBlend":
                        BlendState = BlendState.AlphaBlend;
                        break;
                    case "Additive":
                        BlendState = BlendState.Additive;
                        break;
                    case "NonPremultiplied":
                        BlendState = BlendState.NonPremultiplied;
                        break;
                    default:
                        throw new ArgumentException("Unknown BlendState " + value);

                }
            }
        }
    }
}
